package com.youlu.campus.service.english;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.english.UserCompetition;
import com.youlu.campus.entity.english.UserCompetitionInviteValue;
import com.youlu.campus.entity.english.vo.response.CompetitionUserInviteResponse;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.invite.UserInviteRecordService;
import com.youlu.campus.service.visitor.VisitorUserService;
import com.youlu.campus.service.university.UniversityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 竞赛用户邀请处理服务类
 */
@Slf4j
@Service
public class CompetitionUserInviteService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ActivityTaskService activityTaskService;

    @Autowired
    private UserInviteRecordService userInviteRecordService;

    @Autowired
    private UserCompetitionService userCompetitionService;

    @Autowired
    private VisitorUserService visitorUserService;

    @Autowired
    private UniversityService universityService;

    @Autowired
    private CacheActivityService cacheActivityService;


    public CompetitionUserInviteResponse caInvite(String activityId, String userId) {
        log.info("活动id {} 用户 {} 查看邀请信息", activityId, userId);
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        CompetitionUserInviteResponse competitionUserInvite = new CompetitionUserInviteResponse();
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        String taskId = activityTaskInfo.getId();
        competitionUserInvite.setCaType("邀请");
        competitionUserInvite.setDetail(activityInfo.getDetail());
        competitionUserInvite.setActivityId(activityId);
        competitionUserInvite.setTaskId(taskId);
        competitionUserInvite.setBeforeSignUpDetail(activityInfo.getBeforeSignUpDetail());
        competitionUserInvite.setInviteBackGroundImageUrl(activityTaskInfo.getInviteBackGroundImageUrl());
        UserCompetitionInviteValue userCompetitionInviteValue = findByUserId(userId, taskId, activityId);
        if (Objects.isNull(userCompetitionInviteValue)) {
            competitionUserInvite.setInviteValue(0);
        } else {
            competitionUserInvite.setInviteValue(userCompetitionInviteValue.getQuantity().intValue());
        }
        matchRule(activityTaskInfo, activityId, competitionUserInvite);
        return competitionUserInvite;
    }

    public void matchRule(ActivityTaskInfo activityTaskInfo, String activityId,
                          CompetitionUserInviteResponse competitionUserInvite) {
        Integer inviteValue = competitionUserInvite.getInviteValue();
        Query query = new Query();
        query.addCriteria(Criteria.where("taskId").is(activityTaskInfo.getId()));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.with(Sort.by(Sort.Direction.DESC, "priority"));
        List<ActivityRewardRule> rewardRuleList = this.mongoTemplate.find(query, ActivityRewardRule.class);
        if (CollectionUtils.isEmpty(rewardRuleList)) {
            throw new BusinessException("未配置邀请奖励规则");
        }
        Optional<ActivityRewardRule> sectionOptional =
                rewardRuleList.stream().filter(rewardRule -> ActivityRewardRule.SECTION.equals(rewardRule.getInviteOperatorType()) && (inviteValue >= rewardRule.getInviteStart().intValue() && inviteValue <= rewardRule.getInviteEnd().intValue())).findAny();
        if (sectionOptional.isPresent()) {
            ActivityRewardRule activityRewardRule = sectionOptional.get();
            competitionUserInvite.setPriority(activityRewardRule.getPriority());
            buildUserInvite(activityTaskInfo, activityRewardRule, competitionUserInvite);
            return;
        }
        Optional<ActivityRewardRule> rightIntervalOptional =
                rewardRuleList.stream().filter(rewardRule -> ActivityRewardRule.RIGHT_INTERVAL.equals(rewardRule.getInviteOperatorType()) && (inviteValue >= rewardRule.getInviteEnd().intValue())).findAny();
        if (rightIntervalOptional.isPresent()) {
            ActivityRewardRule activityRewardRule = rightIntervalOptional.get();
            competitionUserInvite.setPriority(activityRewardRule.getPriority());
            buildUserInvite(activityTaskInfo, activityRewardRule, competitionUserInvite);
            return;
        }
        Optional<ActivityRewardRule> equalsOptional =
                rewardRuleList.stream().filter(rewardRule -> ActivityRewardRule.EQUALS.equals(rewardRule.getInviteOperatorType()) && (inviteValue.equals(rewardRule.getInviteEqu().intValue()))).findAny();
        if (equalsOptional.isPresent()) {
            ActivityRewardRule activityRewardRule = equalsOptional.get();
            competitionUserInvite.setPriority(activityRewardRule.getPriority());
            buildUserInvite(activityTaskInfo, activityRewardRule, competitionUserInvite);
            return;
        }
        Optional<ActivityRewardRule> leftIntervalOptional =
                rewardRuleList.stream().filter(rewardRule -> ActivityRewardRule.LEFT_INTERVAL.equals(rewardRule.getInviteOperatorType()) && (inviteValue <= rewardRule.getInviteStart().intValue())).findAny();
        if (leftIntervalOptional.isPresent()) {
            ActivityRewardRule activityRewardRule = leftIntervalOptional.get();
            competitionUserInvite.setPriority(activityRewardRule.getPriority());
            buildUserInvite(activityTaskInfo, activityRewardRule, competitionUserInvite);
            return;
        }


    }

    /**
     * 构建邀请提示语
     *
     * @param activityTaskInfo
     * @param activityRewardRule
     * @param competitionUserInvite
     */
    private void buildUserInvite(ActivityTaskInfo activityTaskInfo, ActivityRewardRule activityRewardRule,
                                 CompetitionUserInviteResponse competitionUserInvite) {
        competitionUserInvite.setCaLevel(activityRewardRule.getCaName());
        if (activityRewardRule.getReplaced()) {

            Double nextCaQ = activityRewardRule.getNextCaQ();
            Integer nextCaValue = nextCaQ.intValue() - competitionUserInvite.getInviteValue();
            switch (activityTaskInfo.getProgressBarType()) {
                // 积分
                case "point": {
                    if (StringUtils.isNotBlank(activityRewardRule.getTips()) && activityRewardRule.getTips().contains("%d") && activityRewardRule.getTips().contains("%s")) {
                        Double b = Math.ceil(nextCaValue);
                        competitionUserInvite.setTips(String.format(activityRewardRule.getTips(), b.intValue(),
                                activityRewardRule.getNextCaName()));
                    }

                }
                break;
                // 邀请人数
                case "invited-num": {
                    if (StringUtils.isNotBlank(activityRewardRule.getTips()) && activityRewardRule.getTips().contains("%d") && activityRewardRule.getTips().contains("%s")) {
                        Double b = Math.ceil(nextCaValue / (activityTaskInfo.getRatio() == null ? 1 :
                                activityTaskInfo.getRatio()));
                        competitionUserInvite.setTips(String.format(activityRewardRule.getTips(), b.intValue(),
                                activityRewardRule.getNextCaName()));
                    }
                }
                break;
                // 邀请人数和积分
                case "invited-num-and-point": {
                    if (StringUtils.isNotBlank(activityRewardRule.getTips()) && activityRewardRule.getTips().contains("%d") && activityRewardRule.getTips().contains("%s")) {
                        Double b = Math.ceil(nextCaValue);
                        competitionUserInvite.setTips(String.format(activityRewardRule.getTips(), b.intValue(),
                                activityRewardRule.getNextCaName()));
                    }
                    if (StringUtils.isNotBlank(activityRewardRule.getInviteNumTips()) && activityRewardRule.getInviteNumTips().contains("%d") && activityRewardRule.getInviteNumTips().contains("%s")) {
                        Double b = Math.ceil(nextCaValue / (activityTaskInfo.getRatio() == null ? 1 :
                                activityTaskInfo.getRatio()));
                        competitionUserInvite.setInvitedNumTips(String.format(activityRewardRule.getInviteNumTips(), b.intValue(),
                                activityRewardRule.getNextCaName()));
                    }
                }
                break;
                default:
            }
        } else {
            competitionUserInvite.setTips(activityRewardRule.getTips());
            competitionUserInvite.setInvitedNumTips(activityRewardRule.getInviteNumTips());
        }
        competitionUserInvite.setRate(activityRewardRule.getOrderNo() / activityRewardRule.getOrderTotal());
        competitionUserInvite.setCaReceive(Boolean.TRUE);
        log.info("贡献值-> {}邀请匹配结果- >{}",competitionUserInvite.getInviteValue(), JSON.toJSONString(competitionUserInvite));
    }

    /**
     * 根据活动id、受邀请人id更新邀请人信息
     *
     * @param activityId
     * @param invitedToUserId
     */

    @Async
    public void updateInviteInfo(String activityId, String invitedToUserId, String appId, String platform) {

        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(invitedToUserId)) {
            return;
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        if (Objects.isNull(activityTaskInfo)) {
            return;
        }
        String taskId = activityTaskInfo.getId();
        UserInviteRecord userInviteRecord = userInviteRecordService.getByInvitedToUserId(invitedToUserId, activityId, taskId);
        if (Objects.isNull(userInviteRecord)) {
            log.error("【英语大赛】activityId - > {} | invitedToUserId - >{} 不是受邀人 ", activityId, invitedToUserId);
            return;
        }
        if (userInviteRecord.getJoinStatus()) {
            log.error("【英语大赛】activityId - > {} | invitedToUserId - >{} 受邀人 已加入", activityId, invitedToUserId);
            return;
        }
        boolean updateSuccess = userInviteRecordService.updateUserInviteStatus(userInviteRecord.getInvitedByUserId(), invitedToUserId, activityId, taskId, Boolean.TRUE);
        if (!updateSuccess) {
            return;
        }
        //1、邀请成功加贡献值
        Double ratio = activityTaskInfo.getRatio();
        UserPO invitedByUser = visitorUserService.getUserUserId(platform, appId, userInviteRecord.getInvitedByUserId());
        if (Objects.isNull(invitedByUser)) {
            return;
        }
        UserCompetition userCompetition = userCompetitionService.findByUserId(invitedByUser.getId());
        if (Objects.isNull(userCompetition)) {
            return;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(invitedByUser.getId()));
        query.addCriteria(Criteria.where("taskId").is(activityTaskInfo.getId()));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        UserCompetitionInviteValue userCompetitionInviteValue = findByUserId(invitedByUser.getId(), activityTaskInfo.getId(), activityId);
        if (Objects.isNull(userCompetitionInviteValue)) {
            userCompetitionInviteValue = new UserCompetitionInviteValue();
            userCompetitionInviteValue.setActivityId(activityId);
            userCompetitionInviteValue.setName(userCompetition.getName());
            userCompetitionInviteValue.setTaskId(taskId);
            userCompetitionInviteValue.setUniversityId(userCompetition.getUniversityId());
            userCompetitionInviteValue.setUniversityName(userCompetition.getUniversityName());
            userCompetitionInviteValue.setUserId(userCompetition.getUserId());
            UniversityInfo university = universityService.get(userCompetition.getUniversityId());
            if (Objects.nonNull(university)) {
                userCompetitionInviteValue.setUniversityLogo(university.getLogo());
            }
            userCompetitionInviteValue.setQuantity(ratio);
            this.mongoTemplate.save(userCompetitionInviteValue);
            return;
        }
        Update update = new Update();
        update.inc("quantity", ratio);
        update.set("updatedTime", new Date());
        this.mongoTemplate.updateFirst(query, update, UserCompetitionInviteValue.class);
    }

    private UserCompetitionInviteValue findByUserId(String userId, String taskId, String activityId) {
        log.info("查询用户邀请值 userId ->{} | taskId - > {}| activityId - >{}", userId, taskId, activityId);
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("taskId").is(taskId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        return this.mongoTemplate.findOne(query, UserCompetitionInviteValue.class);
    }

}
